<script setup lang="ts">
import { ref, onMounted } from 'vue'
import G6 from '@antv/g6'
import Mock from '@/views/mock/day3'
const mountNode = ref()

const lineDash = [4, 2, 1, 2]
const edgeNmae = 'line-cubic'
// 自定义边
G6.registerEdge(
  edgeNmae,
  {
    /**
     * 单图形的边仅考虑 selected、active 状态，有其他状态需求的用户自己复写这个方法
     * @param  {String} name 状态名称
     * @param  {Object} value 状态值
     * @param  {Edge} edge 边
     */
    setState(name, value, edge: any) {
      const shape = edge.get('keyShape')
      if (name === 'active') {
        if (value) {
          let index = 0
          shape.animate(
            () => {
              index++
              if (index > 9) {
                index = 0
              }
              const res = {
                lineDash,
                lineDashOffset: -index
              }
              // return the params for this frame
              return res
            },
            {
              repeat: true,
              duration: 3000
            }
          )
        } else {
          shape.stopAnimate()
          shape.attr('lineDash', null)
        }
      }
    }
  },
  'cubic-vertical' // 被继承的边类型
)

const init = () => {
  // 定义数据、实例化图、加载数据、渲染图
  const graph = new G6.Graph({
    container: mountNode.value,
    width: document.documentElement.clientWidth * 0.6,
    height: document.documentElement.clientHeight * 0.7,
    animate: true, // 启用动画
    fitView: true, // 自动适配画布大小
    modes: {
      default: ['drag-canvas', 'drag-node', 'zoom-canvas', 'activate-relations']
    },
    defaultNode: {
      type: 'rect',
      style: {
        fill: 'rgb(249, 252, 255)',
        stroke: 'rgb(208, 228, 255)',
        lineWidth: 1,
        radius: 5
      },
      linkPoints: {
        top: true,
        bottom: true,
        left: true,
        right: true,
        size: 2,
        fill: '#fff'
      },
      labelCfg: {
        style: {
          fill: 'rgb(51, 51, 51)',
          fontSize: 5
        }
      }
    },
    layout: {
      type: 'dagre',
      rankdir: 'TB', // 布局的方向 从左至右布局 LR, TB, RL, BT
      // align: '', // 节点对齐方式 对齐到左上角 UL, UR, DL, DR  默认，中间对齐
      nodesep: 20, // 节点之间的间距
      ranksep: 30, // 层之间的间距
      // controlPoints: true, // 节点控制点
      nodesepFunc: () => 1, // 节点之间的间距
      ranksepFunc: () => 1 // 层之间的间距
    },
    defaultEdge: {
      type: edgeNmae,
      style: {
        lineWidth: 0.5,
        stroke: 'rgb(51, 136, 255)',
        endArrow: {
          // svg path语法 M表示移动到指定的位置，L表示画一条直线到指定的位置，Z表示闭合路径
          path: 'M 0,0 L 2,1 L 2,-1 Z',
          fill: 'rgb(51, 136, 255)'
        }
      }
    }

    // nodeStateStyles: {
    //   hover: {
    //     lineWidth: 1
    //   }
    // }
    // edgeStateStyles: {
    //   active: {
    //     lineDash: [2, 2]
    //   }
    // }
  })
  // activate-relations 相关时机事件
  graph.on('afteractivaterelations', (e: { item: any; action: string }) => {
    const { item, action } = e
    // 当前操作的节点 item
    if (action === 'activate') {
      graph.setItemState(e.item, 'hover', true)
    } else {
      graph.setItemState(item, 'hover', false)
    }
  })
  // @ts-ignore
  graph.data(Mock) //  加载数据
  graph.render() // 渲染图
}

onMounted(() => {
  init()
})
</script>
<template>
  <div ref="mountNode" class="container" />
</template>

<style lang="scss" scoped>
.container {
  border: 4px solid #5b8ff9;
}
</style>
